﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using Elastic.Clients.Elasticsearch.IndexLifecycleManagement;
using Furion.JsonSerialization;
using Furion.LinqBuilder;
using NewLife.Reflection;
using NewLife.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SL.NET.Core.Service;
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static MyDemo.Application.Service.Plc.MqttService;
using JsonHelper = SL.NET.Core.Helper.JsonHelper;

namespace WCS.Application.Service.Rcs
{
    /// <summary>
    /// 表示车辆在特定时间点的状态
    /// </summary>
    public class VehicleState
    {
        public (int x, int y) Position { get; set; } // 位置坐标
        public DateTime Time { get; set; } // 时间戳
        public Direction Direction { get; set; } // 移动方向
        public int Speed { get; set; } // 移动速度
        public string VehicleId { get; set; } // 车辆编号
        public int TargetFloor { get; set; } // 所在楼层
    }

    /// <summary>
    /// 表示移动方向的枚举
    /// </summary>
    public enum Direction
    {
        Up,
        Right,
        Down,
        Left,
        None
    }

    /// <summary>
    /// 带过期时间的禁行点位
    /// </summary>
    public class BlockedPoint
    {
        public string VehicleId { get; set; } // 禁行点所属车辆ID
        public int TargetFloor { get; set; } // 所在楼层
        public (int x, int y) Position { get; set; }
        public DateTime ExpireTime { get; set; } // 过期时间（车辆离开后30秒）

        // 计算并设置过期时间（车辆通过后30秒）
        public void SetExpireTime(DateTime passTime) => ExpireTime = passTime.AddSeconds(30);
        public bool IsExpired => ExpireTime < DateTime.Now; // 判断是否过期
    }

    /// <summary>
    /// 全局状态与冲突点管理器
    /// 跟踪所有车辆的位置、时间信息及冲突点
    /// </summary>
    public class GlobalManager
    {
        private readonly GlobalManager _globalManager;
        // 1. 在GlobalManager中增加异常点位记录
        private readonly ConcurrentDictionary<string, int> _problemPoints =
            new ConcurrentDictionary<string, int>(); // 记录点位冲突次数
        // 按楼层存储车辆状态历史：Floor -> Position -> VehicleStates
        private readonly ConcurrentDictionary<int, ConcurrentDictionary<(int, int), List<VehicleState>>> _floorStates =
            new ConcurrentDictionary<int, ConcurrentDictionary<(int, int), List<VehicleState>>>();

        // 存储所有冲突点：Floor_PositionX_PositionY -> BlockedPoint
        private readonly ConcurrentDictionary<string, BlockedPoint> _blockedPoints = new ConcurrentDictionary<string, BlockedPoint>();

        // 历史路径存储：VehicleId_Floor -> Path
        private readonly ConcurrentDictionary<string, List<(int x, int y)>> _historicalPaths = new ConcurrentDictionary<string, List<(int x, int y)>>();

        /// <summary>
        /// 添加异常点位记录（冲突次数+1）
        /// </summary>
        public void AddProblemPoint(string pointKey)
        {
            _problemPoints.AddOrUpdate(pointKey, 1, (key, count) => count + 1);
        }

        [ApiDescriptionSettings(Name = "GetProblemPoints"), HttpGet]
        public Dictionary<string, int> GetProblemPoints(int? floor = null)
        {
            if (_globalManager == null)
            {
                return new Dictionary<string, int>(); // 返回空字典而非 null
            }

            if (floor.HasValue)
            {
                return _globalManager.GetProblemPointsByFloor(floor.Value);
            }

            return _globalManager.GetProblemPoints();
        }

        /// <summary>
        /// 获取指定楼层的异常点位统计
        /// </summary>
        public Dictionary<string, int> GetProblemPointsByFloor(int floor)
        {
            return _problemPoints
                .Where(p => p.Key.StartsWith($"{floor}_"))
                .ToDictionary(p => p.Key, p => p.Value);
        }

        /// <summary>
        /// 检查在指定时间点和方向通过某点位是否会发生冲突
        /// </summary>
        public bool CheckConflict(
    int floor,
    (int x, int y) position,
    DateTime time,
    Direction direction,
    string vehicleId,
    bool allowSameVehicleConflict = false)
        {
            // 确保楼层状态字典存在
            _floorStates.TryGetValue(floor, out var floorStates);
            if (floorStates == null) return false;

            // 检查状态冲突
            if (floorStates.TryGetValue(position, out var states))
            {
                foreach (var state in states)
                {
                    if (state.VehicleId == vehicleId) continue;

                    var currentEntryTime = time;
                    var currentExitTime = time.AddSeconds(1);
                    var existingEntryTime = state.Time;
                    var existingExitTime = state.Time.AddSeconds(1);
                    var timeOverlap = currentEntryTime < existingExitTime && existingEntryTime < currentExitTime;

                    if (timeOverlap)
                    {
                        // 新增：记录冲突点位（可选，避免重复记录）
                        var pointKey = $"{floor}_{position.x}_{position.y}";
                        AddProblemPoint(pointKey);

                        if (state.Direction == direction && (currentEntryTime - existingEntryTime).TotalSeconds < 1) return true;
                        if (IsOppositeDirection(state.Direction, direction) && currentEntryTime <= existingExitTime && currentExitTime >= existingEntryTime) return true;
                        if (IsCrossDirection(state.Direction, direction) && (currentEntryTime - existingEntryTime).TotalSeconds < 1) return true;
                    }
                }
            }

            // 检查冲突点
            var blockedPointKey = $"{floor}_{position.x}_{position.y}";
            if (_blockedPoints.TryGetValue(blockedPointKey, out var blockedPoint) &&
                !blockedPoint.IsExpired &&
                (blockedPoint.VehicleId != vehicleId || !allowSameVehicleConflict))
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// 添加车辆状态到全局管理器
        /// </summary>
        public void AddState(VehicleState state)
        {
            // 确保楼层状态字典存在
            _floorStates.AddOrUpdate(state.TargetFloor,
                _ => new ConcurrentDictionary<(int, int), List<VehicleState>>(),
                (floor, dict) => dict);

            _floorStates[state.TargetFloor].AddOrUpdate(state.Position,
                _ => new List<VehicleState> { state },
                (pos, list) =>
                {
                    list.Add(state);
                    return list;
                });
        }

        /// <summary>
        /// 添加冲突点（车辆离开后30秒过期）
        /// </summary>
        public void AddBlockedPoint(int floor, (int x, int y) position, string vehicleId, DateTime passTime)
        {
            var blockedPoint = new BlockedPoint
            {
                VehicleId = vehicleId,
                TargetFloor = floor,
                Position = position
            };
            blockedPoint.SetExpireTime(passTime); // 设置过期时间

            var key = $"{floor}_{position.x}_{position.y}";
            _blockedPoints[key] = blockedPoint;
        }

        /// <summary>
        /// 获取当前楼层有效的冲突点
        /// </summary>
        public List<BlockedPoint> GetActiveBlockedPoints(int floor)
        {
            var ss = _blockedPoints.Values
                .ToList();
            return _blockedPoints.Values
                .Where(p => p.TargetFloor == floor && !p.IsExpired)
                .ToList();
        }

        /// <summary>
        /// 记录历史路径
        /// </summary>
        public void RecordHistoricalPath(string vehicleId, int floor, List<(int x, int y)> path)
        {
            var key = $"{vehicleId}_{floor}";
            _historicalPaths[key] = path;
        }

        /// <summary>
        /// 获取历史路径
        /// </summary>
        public List<(int x, int y)> GetHistoricalPath(string vehicleId, int floor)
        {
            var key = $"{vehicleId}_{floor}";
            return _historicalPaths.TryGetValue(key, out var path) ? path : null;
        }

        /// <summary>
        /// 清理过期冲突点（外部调用）
        /// </summary>
        public void CleanupExpiredBlockedPoints()
        {
            var expiredKeys = _blockedPoints.Keys
                .Where(k => _blockedPoints[k].IsExpired)
                .ToList();

            foreach (var key in expiredKeys)
            {
                _blockedPoints.TryRemove(key, out _);
            }
        }

        /// <summary>
        /// 判断两个方向是否相反
        /// </summary>
        private bool IsOppositeDirection(Direction dir1, Direction dir2)
        {
            return (dir1 == Direction.Up && dir2 == Direction.Down) ||
                   (dir1 == Direction.Down && dir2 == Direction.Up) ||
                   (dir1 == Direction.Left && dir2 == Direction.Right) ||
                   (dir1 == Direction.Right && dir2 == Direction.Left);
        }

        /// <summary>
        /// 判断两个方向是否交叉
        /// </summary>
        private bool IsCrossDirection(Direction dir1, Direction dir2)
        {
            return (dir1 == Direction.Up && (dir2 == Direction.Left || dir2 == Direction.Right)) ||
                   (dir1 == Direction.Down && (dir2 == Direction.Left || dir2 == Direction.Right)) ||
                   (dir1 == Direction.Left && (dir2 == Direction.Up || dir2 == Direction.Down)) ||
                   (dir1 == Direction.Right && (dir2 == Direction.Up || dir2 == Direction.Down));
        }
    }

    /// <summary>
    /// A*寻路算法实现
    /// </summary>
    public class AStar
    {
        // : IDynamicApiController, ITransient
        //private readonly SysCacheService _sysCacheService;
        //public AStar(SysCacheService sysCacheService)
        //{
        //    _sysCacheService = sysCacheService;

        //}


        private static readonly (int x, int y)[] Directions = new (int x, int y)[]
        {
            (0, 1),   // 右
            (1, 0),   // 下
            (0, -1),  // 左
            (-1, 0)   // 上
        };

        /// <summary>
        /// 使用A*算法寻找从起点到终点的路径
        /// </summary>
        /// <summary>
        /// 使用A*算法寻找从起点到终点的路径
        /// </summary>
        public List<(int x, int y)> FindPath(
            string vehicleId,
            int targetFloor,
            (int x, int y) start,
            (int x, int y) goal,
            int[,] grid,
            GlobalManager manager,
            int speed = 1,
            List<(int X, int Y)> blockedPoints = null)
        {
            var openSet = new SortedSet<(int f, (int x, int y) pos, DateTime time)>();
            var startTime = DateTime.Now;
            openSet.Add((0, start, startTime));

            var cameFrom = new Dictionary<(int, int), (int x, int y, DateTime time)>();
            var gScore = new Dictionary<(int, int), int> { [start] = 0 };

            while (openSet.Count > 0)
            {
                var current = openSet.Min;
                openSet.Remove(current);

                if (current.pos == goal)
                    return ReconstructPath(cameFrom, current);

                foreach (var direction in Directions)
                {
                    var neighbor = (current.pos.x + direction.x, current.pos.y + direction.y);
                    var newTime = current.time.AddSeconds(speed);
                    var moveDir = CalculateDirection(current.pos, neighbor);
                   

                    // 跳过禁行点位
                    if (blockedPoints != null && blockedPoints.Any(p => p.X == neighbor.Item1 && p.Y == neighbor.Item2))
                    {
                        continue;
                    }

                    // 新增：根据异常点位调整路径代价
                    var pointKey = $"{targetFloor}_{neighbor.Item1}_{neighbor.Item2}";
                    var problemPoints = manager.GetProblemPoints();
                    int conflictPenalty = 0;

                    if (problemPoints.TryGetValue(pointKey, out var conflictCount) && conflictCount > 0)
                    {
                        // 冲突次数越多，路径代价越高（示例：每次冲突增加5点代价）
                        conflictPenalty = conflictCount * 5;
                    }

                    if (IsValidMove(neighbor, grid) &&
                        !manager.CheckConflict(targetFloor, neighbor, newTime, moveDir, vehicleId) &&
                        (!gScore.ContainsKey(neighbor) || current.f + speed + conflictPenalty < gScore[neighbor]))
                    {
                        cameFrom[neighbor] = (current.pos.x, current.pos.y, current.time);
                        gScore[neighbor] = current.f + speed + conflictPenalty;

                        var h = Heuristic(neighbor, goal);
                        openSet.Add((gScore[neighbor] + h, neighbor, newTime));
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// 计算从一个点到另一个点的移动方向
        /// </summary>
        internal static Direction CalculateDirection((int x, int y) from, (int x, int y) to)
        {
            var dx = to.x - from.x;
            var dy = to.y - from.y;

            return dx switch
            {
                1 => Direction.Right,
                -1 => Direction.Left,
                _ when dy == 1 => Direction.Down,
                _ when dy == -1 => Direction.Up,
                _ => throw new ArgumentException("Invalid direction")
            };
        }

        /// <summary>
        /// 检查移动是否有效（在地图范围内且不是障碍物）
        /// </summary>
        private bool IsValidMove((int x, int y) position, int[,] grid)
        {
            return position.x >= 0 && position.x < grid.GetLength(0) &&
                   position.y >= 0 && position.y < grid.GetLength(1) &&
                   grid[position.x, position.y] == 0;
        }

        /// <summary>
        /// 启发式函数：计算从当前点到目标点的估计距离（曼哈顿距离）
        /// </summary>
        private int Heuristic((int x, int y) a, (int x, int y) b)
        {
            return Math.Abs(a.x - b.x) + Math.Abs(a.y - b.y);
        }

        /// <summary>
        /// 根据回溯信息重建路径
        /// </summary>
        private List<(int x, int y)> ReconstructPath(
            Dictionary<(int, int), (int x, int y, DateTime time)> cameFrom,
            (int f, (int x, int y) pos, DateTime time) current)
        {
            var path = new List<(int x, int y)>();
            path.Add(current.pos);

            while (cameFrom.TryGetValue((current.pos.x, current.pos.y), out var prev))
            {
                path.Add((prev.x, prev.y));
                current = (current.f, (prev.x, prev.y), prev.time);
            }

            path.Reverse(); // 反转路径，使其从起点到终点
            return path;
        }
    }

    /// <summary>
    /// 表示需要规划路径的车辆
    /// </summary>
    public class Vehicle
    {
        public string VehicleId { get; set; }
        public int TargetFloor { get; set; }
        public (int x, int y) Start { get; set; }
        public (int x, int y) End { get; set; }
        public int Speed { get; set; } = 1; // 移动速度(格/秒)

        public Vehicle(string vehicleId, int targetFloor, (int x, int y) start, (int x, int y) end, int speed = 1)
        {
            VehicleId = vehicleId;
            TargetFloor = targetFloor;
            Start = start;
            End = end;
            Speed = speed;
        }
    }

    /// <summary>
    /// 路径规划结果类
    /// </summary>
    public class PathResult
    {
        public Vehicle Vehicle { get; }
        public List<(int x, int y)> Path { get; }
        public Dictionary<(int x, int y), (DateTime time, Direction dir)> StateData { get; }

        public PathResult(Vehicle vehicle, List<(int x, int y)> path)
        {
            Vehicle = vehicle;
            Path = path;
            StateData = new Dictionary<(int x, int y), (DateTime, Direction)>();

            // 计算路径上每个点的时间和方向信息
            var currentTime = DateTime.Now;
            for (int i = 0; i < path.Count - 1; i++)
            {
                var next = path[i + 1];
                var direction = AStar.CalculateDirection(path[i], next);
                currentTime = currentTime.AddSeconds(vehicle.Speed);
                StateData[path[i]] = (currentTime, direction);
            }
        }
    }


    /// <summary>
    /// AGV调度服务
    /// 负责多车辆路径规划、冲突检测与协调
    /// </summary>
    [ApiDescriptionSettings(groups: ApplicationConst.GroupName, Order = 13)]
    [AllowAnonymous]
    public class RcsService : IDynamicApiController, ITransient
    {
        private readonly ILogger _logger;
        private readonly GlobalManager _globalManager = new GlobalManager(); // 全局管理器
        private readonly int[,] _grid;
        private const int MaxRetryCount = 3; // 最大重试次数
        private const int ConflictPointExpireSeconds = 30; // 冲突点过期时间（秒）
                                                           //redis
        private readonly SysCacheService _sysCacheService;

        public RcsService(ILogger<RcsService> logger, SysCacheService sysCacheService)
        {
            _logger = logger;
            _sysCacheService = sysCacheService;
            _grid = new int[,]
  {
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, //  (3) 3,3     (2) 3,15 
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1},   //  (5)    11,3
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, //  (4)  23,3     (1) 23,15
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1}
  };
        
        }

        /// <summary>
        /// 查询并返回车辆的路径规划结果
        /// </summary>
        [ApiDescriptionSettings(Name = "select"), HttpPost]
        [DisplayName("查询")]
        public async Task<RcsResponse> QueryAsync(List<Vehicle> vehicles)
        {
            try
            {
                var successfulPaths = new List<(Vehicle vehicle, List<(int x, int y)> path)>();
                foreach (var vehicle in vehicles)
                {
                    SerilogHelper.WriteLog("QueryAsync", "vehicle", JsonHelper.ObjectToJson(vehicle));

                    List<(int x, int y)> path = null;
                    int retryCount = 0;
                    bool pathFound = false;

                    // 清理过期冲突点（可以考虑在循环外统一清理一次，这里先保持在每个车辆规划前清理）
                    _globalManager.CleanupExpiredBlockedPoints();

                    // 路径规划主逻辑，支持重试
                    while (retryCount < MaxRetryCount)
                    {
                        // 获取当前有效的冲突点
                        //var activeBlockedPoints = _globalManager.GetActiveBlockedPoints(vehicle.TargetFloor);
                        //存放全部遍历到的数据
                        var sdsds= new List<(int x, int y)>();
                        //每个redis的数据
                        var activeBlockedPoints = new List<(int x, int y)>();
                        //var  activeBlockedPoints = "";
                        ////获取redis数据
                        //获取车辆数据
                        var Vehicleidcode =  App.GetConfig<List<DerivesInfo>>("MQTT:Devices").Where(it => it.DeviceType == 0);

                        foreach (var x in Vehicleidcode)
                        {
                            var json = _sysCacheService.Get<string>(x.DeviceId+ "Point");
                            //activeBlockedPoints = _sysCacheService.Get<List<(int x,int y)>>(x.DeviceId);
                            activeBlockedPoints = JsonHelper.JsonToObject<List<(int x, int y)>>(json);
                            if (vehicle.TargetFloor == x.Storey)
                            {
                                if (activeBlockedPoints != null && activeBlockedPoints.Count>0)
                                {
                                    foreach (var item in activeBlockedPoints)
                                    {
                                        sdsds.Add(item);
                                    }
                                    if (vehicle.VehicleId == x.DeviceId)
                                    {
                                        foreach (var item in activeBlockedPoints)
                                        {
                                            sdsds.Remove(item);
                                        }
                                    }
                                }
                            }

                        }
                        //agv小车数据
                        var AgvPoint = App.GetConfig<List<DerivesInfo>>("MQTT:Devices").Where(it => it.DeviceType == 0);
                        SerilogHelper.WriteLog("QueryAsync", "AgvPoint", JsonHelper.ObjectToJson(AgvPoint));
                        foreach (var item in AgvPoint)
                        {
                            var rgv = _sysCacheService.Get<DerivesInfo>(item.DeviceId);
                            SerilogHelper.WriteLog("QueryAsync", "rgv", JsonHelper.ObjectToJson(rgv));
                            if (rgv != null)
                            {
                                string[] parts = rgv?.LocationPoint?.Split(',');
                                if (parts is not null && parts.Length == 2)
                                {
                                    int x = int.Parse(parts[0]);
                                    int y = int.Parse(parts[1]);
                                    var LocationPoints = (x, y);
                                    if ( vehicle.TargetFloor == item.Storey && vehicle.VehicleId != rgv.DeviceId)
                                    {
                                        sdsds.Add(LocationPoints);
                                    }
                                }
                            }
                        }
                        SerilogHelper.WriteLog("QueryAsync", "AllPoint", JsonHelper.ObjectToJson(sdsds));
                        //var jsonResult = _sysCacheService.Get<List<(int X, int Y)>>(vehicle.VehicleId);
                        //if (sdsds.Count()!=0)
                        //{
                        //    activeBlockedPoints = sdsds;
                        //}



                        //差一个判断当前车辆编码是否与缓存中一致 如果一致那就传空的过去

                        // 执行路径规划
                        path = await PlanVehiclePathAsync(vehicle, sdsds);

                        if (path != null)
                        {
                            /* // 检查路径冲突
                             var conflicts = CheckPathConflicts(vehicle, activeBlockedPoints);

                             if (conflicts.Any())
                             {
                                 // 处理冲突，添加到冲突点管理
                                 //HandleConflicts(vehicle, path, conflicts);
                                 retryCount++;
                                 continue; // 重试规划
                             }*/
                            retryCount++;
                            pathFound = true;
                            break;
                        }

                        //retryCount++;
                        if (path.Count()==0)
                        {
                            await Task.Delay(5000); // 等待5秒后重试
                        }    
                       
                    }

                    if (!pathFound)
                    {
                        // 这里可以考虑记录下是哪辆车路径规划失败，然后根据配置或需求决定是否继续处理其他车辆
                        // 目前简单返回失败响应
                        return new RcsResponse
                        {
                            Code = 500,
                            Message = $"车辆 {vehicle.VehicleId} 路径规划失败，已达到最大重试次数",
                            Result = null,
                            IsSuccess = false
                        };
                    }

                    // 记录路径到历史存储
                    //_globalManager.RecordHistoricalPath(vehicle.VehicleId, vehicle.TargetFloor, path);

                    // 记录路径状态
                    //RecordPathState(vehicle, path);

                    successfulPaths.Add((vehicle, path));
                }

                return new RcsResponse
                {
                    Code = 200,
                    Message = "成功",
                    Result = successfulPaths.Select(p => new RcsResult
                    {
                        VehicleId = p.vehicle.VehicleId,
                        TargetFloor = p.vehicle.TargetFloor,
                        Start = p.vehicle.Start,
                        End = p.vehicle.End,
                        Path = p.path
                    }).ToList(),
                    IsSuccess = true
                };
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog("QueryAsync", ex);
                _logger.LogError(ex, "路径规划服务异常");
                return new RcsResponse
                {
                    Code = 500,
                    Message = $"路径规划失败: {ex.Message}",
                    Result = new List<RcsResult>(),
                    IsSuccess = false
                };
            }
        }
        [ApiDescriptionSettings(Name = "GetBlockedPoints"),HttpPost]
        public List<BlockedPoint> GetBlockedPoints(int? floor = null)
        {
            if (floor.HasValue)
            {
                return _globalManager.GetActiveBlockedPoints(floor.Value);
            }
            return null;
          
        }
        /// <summary>
        /// 异步规划车辆路径
        /// </summary>
        private async Task<List<(int x, int y)>> PlanVehiclePathAsync(Vehicle vehicle, List<(int X, int Y)> blockedPoints)
        {
            return await Task.Run(() => new AStar().FindPath(
                vehicle.VehicleId,
                vehicle.TargetFloor,
                vehicle.Start,
                vehicle.End,
                _grid,
                _globalManager,
                vehicle.Speed,
                blockedPoints));
        }

        /// <summary>
        /// 检查路径冲突
        /// </summary>
        private List<((int x, int y) point, Direction dir, DateTime time)> CheckPathConflicts(Vehicle vehicle, List<(int x, int y)> path)
        {
            var conflicts = new List<((int x, int y) point, Direction dir, DateTime time)>();
            var pathStates = GetPathStates(vehicle, path);

            foreach (var state in pathStates)
            {
                if (_globalManager.CheckConflict(
                    vehicle.TargetFloor,
                    state.Key,
                    state.Value.time,
                    state.Value.dir,
                    vehicle.VehicleId))
                {
                    conflicts.Add((state.Key, state.Value.dir, state.Value.time));
                }
            }

            return conflicts;
        }

        /// <summary>
        /// 获取路径上每个点的详细状态，包括时间和方向
        /// </summary>
        private Dictionary<(int x, int y), (DateTime time, Direction dir)> GetPathStates(Vehicle vehicle, List<(int x, int y)> path)
        {
            var states = new Dictionary<(int x, int y), (DateTime, Direction)>();
            DateTime time = DateTime.Now;

            for (int i = 0; i < path.Count - 1; i++)
            {
                var position = path[i];
                Direction direction = AStar.CalculateDirection(position, path[i + 1]);

                // 计算到达时间
                time = time.AddSeconds(vehicle.Speed);

                states[position] = (time, direction);
            }

            return states;
        }

        /// <summary>
        /// 处理路径冲突，添加冲突点到全局管理器
        /// </summary>
        private void HandleConflicts(Vehicle vehicle, List<(int x, int y)> path, List<((int x, int y) point, Direction dir, DateTime time)> conflicts)
        {
            Console.WriteLine($"处理车辆{vehicle.VehicleId}的冲突点，共{conflicts.Count}个");
            foreach (var conflict in conflicts)
            {
                var exitTime = conflict.time.AddSeconds(1);
                _globalManager.AddBlockedPoint(vehicle.TargetFloor, conflict.point, vehicle.VehicleId, exitTime);
                Console.WriteLine($"添加冲突点: 楼层={vehicle.TargetFloor}, 位置=({conflict.point.x},{conflict.point.y}), 车辆={vehicle.VehicleId}, 过期时间={exitTime.AddSeconds(ConflictPointExpireSeconds)}");

                // 新增：记录异常点位冲突次数
                var pointKey = $"{vehicle.TargetFloor}_{conflict.point.x}_{conflict.point.y}";
                _globalManager.AddProblemPoint(pointKey);
            }
        }
    }
}